﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Serialization;


namespace SmartHelper
{
    /// <summary>
    /// 类型转换帮助类
    /// </summary>
    public class ConvertHelper 
    {
        #region 表转换成实体
        /// <summary>
        /// 大小写和类型要一致，转换先找属性再找字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataRow"></param>
        /// <param name="entity"></param>
        public static void DataRowToEntity<T>(DataRow dataRow, out T entity) where T : new()
        {
            DataTable table = dataRow.Table;
            entity = ((default(T) == null) ? Activator.CreateInstance<T>() : default(T));
            //ORMappingItemCollection mappingInfo = ORMapping.GetMappingInfo<T>();
            IEnumerator enumerator = table.Columns.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    DataColumn dataColumn = (DataColumn)enumerator.Current;
                    if (!dataRow.IsNull(dataColumn))
                    {
                        string columnName = dataColumn.ColumnName;
                        //string text = mappingInfo.Contains(columnName) ? mappingInfo.get_Item(columnName).PropertyName : columnName;
                        string text = columnName;
                        PropertyInfo property = typeof(T).GetProperty(text);
                        if (property == null)
                        {
                            FieldInfo field = typeof(T).GetField(text);
                            if (field != null)
                            {
                                if (field.FieldType.IsEnum)
                                {
                                    field.SetValue(entity, Enum.Parse(field.FieldType, dataRow[columnName].ToString()));
                                }
                                else
                                {
                                    if (dataRow[columnName] is byte)
                                    {
                                        field.SetValue(entity, int.Parse(dataRow[columnName].ToString()));
                                    }
                                    else
                                    {
                                        field.SetValue(entity, dataRow[columnName]);
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (property.CanWrite)
                            {
                                if (property.PropertyType.IsEnum)
                                {
                                    property.SetValue(entity, Enum.Parse(property.PropertyType, dataRow[columnName].ToString()), null);
                                }
                                else
                                {
                                    if (dataRow[columnName] is byte)
                                    {
                                        property.SetValue(entity, int.Parse(dataRow[columnName].ToString()), null);
                                    }
                                    else
                                    {
                                        property.SetValue(entity, dataRow[columnName], null);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
        public static T DataRowToEntity<T>(DataRow dr) where T : new()
        {
            T result = new T();
            //result.GetType().GetProperties().AsParallel().ForAll(it =>
            //{
            //    object[] attrs = it.GetCustomAttributes(typeof(ColumnAttribute), true);
            //    if (attrs.Length > 0)
            //    {
            //        ColumnAttribute attr = attrs[0] as ColumnAttribute;
            //        if (dr.Table.Columns.Contains(attr.Name))
            //        {
            //            it.SetValue(result, StringToOtherType(dr[attr.Name].ToString(), it.PropertyType.FullName.ToLower()));
            //        }
            //    }
            //});
            return result;
        }
        public Dictionary<string, string> DataTableToDictionary(DataTable dt, string keyField, string valueField)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 表转换成list实体集合，类属性必须添加特性ColumnAttribute
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> DataTableToEntities<T>(DataTable dt) where T : new()
        {
            List<T> entities = new List<T>();
            foreach (DataRow item in dt?.Rows)
            {
                entities.Add(DataRowToEntity<T>(item));
            }
            return entities;
        }
        public static void DataTableToEntities<T>(DataTable dt, out List<T> entities) where T : new()
        {
            entities = new List<T>();
            IEnumerator enumerator = dt.Rows.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    DataRow dataRow = (DataRow)enumerator.Current;
                    T t;
                    DataRowToEntity<T>(dataRow, out t);
                    entities.Add(t);
                }
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        } 
        #endregion

        /// <summary>
        /// 类型转换
        /// </summary>
        /// <param name="srcValue"></param>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static object StringToOtherType(string srcValue, string typeName)
        {
            if (srcValue == null)
                return null;
            Object result = null;
            if (typeName.Contains("string"))
            {
                result = srcValue;
            }
            else
            if (typeName.Contains("datetime"))
            {
                DateTime temp;
                if (DateTime.TryParse(srcValue, out temp))
                    result = temp;
            }
            else
            if (typeName.Contains("int32"))
            {
                int temp;
                if (int.TryParse(srcValue, out temp))
                    result = temp;
            }
            else
            if (typeName.Contains("double"))
            {
                double temp;
                if (double.TryParse(srcValue, out temp))
                    result = temp;
            }else
            if (typeName.Contains("bool"))
            {
                bool temp;
                if (bool.TryParse(srcValue, out temp))
                    result = temp;
            }
            return result;
        }

    }

}
